#include "SDLEngine.h"
#include <iostream>

SDLEngine* SDLEngine::instance = 0;

SDLEngine::SDLEngine()
	: isInitialized(false)
{
	if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
	{
		std::cout << "Erreur SDL_Init" << std::endl;
	}

	SDL_WM_SetCaption("SDLEngine", 0);
	SDLRenderer::GetInstance()->SetResolution(800, 600, 32);
	SDLRenderer::GetInstance()->StartRendering();
}

SDLEngine::~SDLEngine()
{
}

void SDLEngine::Init()
{
	m_CurrentScene = new SDLScene("Main");
	AddScene(m_CurrentScene->GetName(), m_CurrentScene);
}

void SDLEngine::Start()
{ 
	if(isInitialized == false)
	{
		m_CurrentScene->Start();
		isInitialized = true;

		Run();
	}
}

bool SDLEngine::SwitchToScene(std::string _scene)
{
	std::map<std::string, SDLScene*>::iterator iter = m_Scenes.find(_scene);

	if(iter != m_Scenes.end())
	{
		m_CurrentScene = iter->second;
		return true;
	}
	else
	{
		std::cerr << "SDLEngine ERROR : Trying to switch to a non-existing scene" << std::endl;
		return false;
	}
}

bool SDLEngine::AddScene(std::string _sceneID, SDLScene* _scene)
{
	std::map<std::string, SDLScene*>::iterator iter = m_Scenes.find(_sceneID);

	if(iter != m_Scenes.end())
	{
		std::cerr << "SDLEngine ERROR : Trying to add a SDLScene with the same ID as an existing SDLScene" << std::endl;
		return false;
	}
	else
	{
		m_Scenes.insert(make_pair(_sceneID, _scene));
		return true;
	}
}

SDLScene* SDLEngine::GetScene(std::string _scene) const
{
	std::map<std::string, SDLScene*>::const_iterator iter = m_Scenes.find(_scene);

	if(iter != m_Scenes.end())
		return iter->second;
	else
	{
		std::cerr << "SDLEngine ERROR : Trying to access a non-existing scene" << std::endl;
		return 0;
	}
}

void SDLEngine::Run()
{
	SDL_Event event;
	bool isRunning = true;

	while(isRunning)
	{
		Update();
		Draw();
		
		while(SDL_PollEvent(&event))
		{
			SDLInput::GetInstance()->Poll(event);

			switch(event.type)
			{
			case SDL_QUIT:
				isRunning = false;
				break;
			case SDL_KEYDOWN:
				switch (event.key.keysym.sym)
				{
				case SDLK_ESCAPE:
					isRunning = false;
					break;
				default:
					break;
				}
			default:
				break;
			}
		}
	}
	Stop();
}

void SDLEngine::Update()
{
	SDLTime::GetInstance()->Tick();
	m_CurrentScene->Update();
}

void SDLEngine::Draw()
{
	SDL_FillRect(SDLRenderer::GetInstance()->GetScreen(), 
				&SDLRenderer::GetInstance()->GetScreen()->clip_rect, 
				SDL_MapRGB(SDLRenderer::GetInstance()->GetScreen()->format, 
				0x00, 0x00, 0x00));
	m_CurrentScene->Draw();

	if(SDL_Flip(SDLRenderer::GetInstance()->GetScreen()) == -1)
	{
		std::cerr << "Error - Flip Screen" << std::endl;
	}
}

void SDLEngine::Stop()
{
	isInitialized = false;
	m_CurrentScene->Stop();
}

